grammar Gramatica;

tokens {
	QUESTION;
	ASTERISK;
	PLUS;
}
@rulecatch { } 
@parser::header { 
	package ar.uba.tleng.g99.expregs.parser;
	import ar.uba.tleng.g99.expregs.automata.*; 
}
@lexer::header { 
	package ar.uba.tleng.g99.expregs.parser; 
}

s	returns [Expr e]
	:	expr {e = $expr.e;};

lambda returns [Expr e]
	: {e = null;} ;

expr returns [Expr e]
	:	orExpr endExpr 
		{
			if ($endExpr.e == null) {
				e = $orExpr.e;
			} else {
				e = new OrExpr($orExpr.e, $endExpr.e);
			}
		};
		
endExpr returns [Expr e]
	:	{e = null;} | '|' expr {e = $expr.e;};

orExpr returns [Expr e]	
	:	concatExpr endOrExpr 
		{
			if ($endOrExpr.e == null) {
				e = $concatExpr.e;
			} else {
				e = new ConcatExpr($concatExpr.e, $endOrExpr.e);
			}
		};

endOrExpr returns [Expr e]
	: lambda {e = null;} | orExpr {e = $orExpr.e;};

concatExpr returns [Expr e]
	:	atomExpr endConcatExpr
		{
			if ($endConcatExpr.t == null) {
				e = $atomExpr.e;
			} else if ($endConcatExpr.t == PLUS) {
				e = new PlusExpr($atomExpr.e);
			} else if ($endConcatExpr.t == ASTERISK) {
				e = new AsteriskExpr($atomExpr.e);
			} else if ($endConcatExpr.t == QUESTION) {
				e = new QuestionExpr($atomExpr.e);
			}
		} 
	;

endConcatExpr returns [Integer t]
	:  lambda {t = null;}
	| '?' e=endConcatExpr {
		if ($e.t == null || $e.t == QUESTION) {
			t = QUESTION;
		} else {
			t = ASTERISK;
		}
	}
	
	| '*' e=endConcatExpr {t = ASTERISK;}
	
	| '+' e=endConcatExpr {
		if ($e.t == null || $e.t == PLUS) {
			t = PLUS;
		} else {
			t = ASTERISK;
		}
	};

atomExpr returns [Expr e]
	:	CHAR { e = new AtomExpr($CHAR.getText().charAt(0)); } 
	| '.' { e = new AtomExpr('.'); } 
	| '(' expr ')' { e = $expr.e; }
	;


CHAR 	:	('a' .. 'z') | ('A' .. 'Z') | ('0' .. '9') | ' ';